home *** CD-ROM | disk | FTP | other *** search
/ JCSM Shareware Collection 1993 November / JCSM Shareware Collection - 1993-11.iso / cl720 / commgeoj.lzh / CGDEMO2.C < prev    next >
Text File  |  1993-06-15  |  57KB  |  1,843 lines

  1. #define  LINT_ARGS
  2.  
  3. #include <math.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. #include "cg.h"
  9.  
  10. #define  C_DEG_TO_RAD        ((real)  0.0174532)           /* 3.1415926 / 180.0                   */
  11. #define  C_CONTINUE          22
  12. #define  C_POINT_MENU        6
  13.  
  14. struct t_menu_item
  15. {
  16.     char                     item[12];
  17.     int                      return_value;
  18.     int                      next_menu;
  19. };
  20.  
  21. int                          current_menu;
  22.  
  23. int                          menus[8] = {0, 6, 8, 9, 17, 26, 35};
  24.  
  25. char                         menu_title[6][12] = {"MAIN",
  26.                                                   "",
  27.                                                   "",
  28.                                                   "LINES",
  29.                                                   "CIRCLES",
  30.                                                   "GET POINT"};
  31.  
  32. struct t_menu_item           menu_items[35] = {"About CG",      1, 2,
  33.                                                "Points",       20, 0,
  34.                                                "Lines",         0, 4,
  35.                                                "Circles",       0, 5,
  36.                                                "Delete",       21, 0,
  37.                                                "Exit",          2, 0,
  38.  
  39.                                                "Continue",     22, 0,
  40.                                                "Return",        0, 1,
  41.  
  42.                                                "Return",        0, 1,
  43.  
  44.                                                "2 pts",        12, 0,
  45.                                                "Horizontal",   13, 0,
  46.                                                "Vertical",     14, 0,
  47.                                                "Parallel",     15, 0,
  48.                                                "Perp To",      16, 0,
  49.                                                "Tan Arc",      18, 0,
  50.                                                "Tan 2 Arcs",   19, 0,
  51.                                                "Return",        0, 1,
  52.  
  53.                                                "3 points",      3, 0,
  54.                                                "Tan Ln Pt",     4, 0,
  55.                                                "Tan Ln 2 Pts",  5, 0,
  56.                                                "Tan 2 Lines",   6, 0,
  57.                                                "Tan 2 Lns Pt",  7, 0,
  58.                                                "Tan 3 Lines",   8, 0,
  59.                                                "Tan 2 Arcs",    9, 0,
  60.                                                "Tan Arc Ln",   11, 0,
  61.                                                "Return",        0, 1,
  62.  
  63.                                                "Element",     201, 0,
  64.                                                "Around Arc",  202, 0,
  65.                                                "Along Line",  203, 0,
  66.                                                "Int 2 Lines", 204, 0,
  67.                                                "Int Arc Ln",  205, 0,
  68.                                                "Int 2 Arcs",  206, 0,
  69.                                                "Coordinate",  207, 0,
  70.                                                "Screen",      208, 0,
  71.                                                "Return",      209, 0};
  72.  
  73. struct t_menu_item           fixed_menu_items[6] = {"ZOOM  ", 101, 0,
  74.                                                     "PAN   ", 102, 0,
  75.                                                     "FULL  ", 103, 0, 
  76.                                                     "SVIEW ", 104, 0,
  77.                                                     "RVIEW ", 105, 0,
  78.                                                     "CLEAR ", 106, 0};
  79.  
  80. char                         intro[33][45] =
  81.    {"CommonGeometry is a library of C functions",
  82.     "that construct 2D geometries, for example ",
  83.     "a LINE TANGENT to 2 ARCS passing through a",
  84.     "POINT or a CIRCLE TANGENT to 2 ARCS with a",
  85.     "given RADIUS, or calculate geometric      ",
  86.     "relationships, such as the INTERSECTION of",
  87.     "2 ARCS, the INTERSECTION of a LINE and an ",
  88.     "ARC, and the DIRECTION from a POINT to a  ",
  89.     "LINE.                                     ",
  90.     "                                          ",
  91.     "CommonGeometry can be used as a building  ",
  92.     "block for CAD, CAM or CAE applications, as",
  93.     "well as many others. CommonGeometry can be",
  94.     "used with CommonGraphics or any other     ",
  95.     "graphics library.                         ",
  96.     "CommonGeometry, like CommonGraphics, is a ",
  97.     "portable library that lets you to develop ",
  98.     "complex graphics applications across a    ",
  99.     "variety of operating systems hardware     ",
  100.     "platforms and graphics environments.      ",
  101.     "                                          ",
  102.     "This program demonstrates many of the     ",
  103.     "functions in CommonGeometry. The menus are",
  104.     "arranged like those of a CAD program. All ",
  105.     "of the graphics you see were developed    ",
  106.     "using CommonGraphics.                     ",
  107.     "Copyright 1993 by Rialto Software         ",
  108.     "4179 Woodland Dr. Suite 15B               ",
  109.     "Ann Arbor MI 48103 (313) 426-5295         ",
  110.     "All rights reserved.                      ",
  111.     "                                          ",
  112.     "CommonGeometry and CommonGraphics are     ",
  113.     "trademarks of Rialto Software             "};
  114.  
  115. t_world_coord                color_menu;
  116. int                          current_menu;
  117. t_world_coord                default_point_menu;
  118. struct t_device              device_params;
  119. real                         distance;
  120. long                         element_id;
  121. t_world_coord                fixed_menu_center;
  122. t_world_coord                graphic_ll;
  123. t_world_coord                graphic_ur;
  124. int                          i;
  125. t_world_coord                menu_center;
  126. bool                         menu_highlighted;
  127. t_world_coord                menu_item_highlight_pt;
  128. int                          menu_highlight_item;
  129. t_world_coord                menu_ll;
  130. t_world_coord                menu_ur;
  131. struct t_request_buffer      pick_buffer;
  132. t_world_coord                pts[6];
  133. bool                         return_menu_item_selected;
  134. int                          save_current_menu;
  135. t_world_coord                save_ll;
  136. t_world_coord                save_ur;
  137. t_world_coord                text_ll;
  138. t_ndc_coord                  viewport_ll;
  139. t_ndc_coord                  viewport_ur;
  140.  
  141. int                          fixed_index;
  142. int                          menu_index;
  143. bool                         prompt_interrupted;
  144.  
  145.  
  146. void display_menu (int);
  147. void display_fixed_menu (void);
  148. void display_color_menu (void);
  149. int  find_menu_picked (void);
  150. bool check_menu_picked (void);
  151. void process_fixed_menu (void);
  152. bool process_point_menu (t_world_coord);
  153. bool valid_prompt (t_name_set, t_name_set, char *);
  154. bool get_point (bool, t_world_coord);
  155. void display_about_cg_info (void);
  156. void point (void);
  157. void delete_element (void);
  158. void line_2pts (void);
  159. void line_pt_angle_distance (real);
  160. void line_parallel (void);
  161. void line_perpendicular (void);
  162. void line_tan_arc (void);
  163. void line_tan_2arcs (void);
  164. void circle_3pts (void);
  165. void circle_tan_line_pt (void);
  166. void circle_tan_line_2pts (void);
  167. void circle_tan_2lines (void);
  168. void circle_tan_2lines_pt (void);
  169. void circle_tan_3lines (void);
  170. void circle_tan_2arcs (void);
  171. void circle_tan_arc_line (void);
  172. void zoom (void);
  173. void main (void);
  174. /**/
  175. void display_menu (int menu_number)
  176.  
  177. {
  178.    int                       index;
  179.    struct t_attributes       attributes;
  180.    t_world_coord             pt;
  181.    t_world_coord             text_pt;
  182.    t_world_coord             tmp_pt;
  183.  
  184.    cg_open_non_retained_structure ("MENU");
  185.    cg_empty_structure ("MENU");
  186.  
  187.    cg_inquire_primitive_attributes (&attributes);
  188.  
  189.    cg_set_text_color (RED);
  190.    cg_set_interior_style (FILL);
  191.    cg_set_line_style (SOLID);
  192.  
  193.    text_pt[0] = menu_center[0] - 20.0;
  194.    text_pt[1] = menu_center[1] - 10.0;
  195.  
  196.    cg_draw_text (STRING_TEXT, text_pt, menu_title[menu_number - 1], 0.0, 0.0, 0.0);
  197.  
  198.    cg_set_text_color (WHITE);
  199.  
  200.    pt[0] = menu_center[0];
  201.    pt[1] = menu_center[1] - 20.0;
  202.  
  203.    for (index = menus[menu_number - 1]; index < menus[menu_number]; index++)
  204.    {
  205.       cg_set_line_color (BLACK);
  206.       tmp_pt[0] = pt[0] - 4.0;
  207.       tmp_pt[1] = pt[1] - 4.0;
  208.       cg_draw_rectangle (tmp_pt, 90.0, 15.0, 5.0, 0.0);
  209.       cg_set_line_color (RED);
  210.       cg_draw_rectangle (pt, 90.0, 15.0, 5.0, 0.0);
  211.       text_pt[0] = pt[0] - 40.0;
  212.       text_pt[1] = pt[1] - 3.0;
  213.       cg_draw_text (STRING_TEXT, text_pt, menu_items[index].item, 0.0, 0.0, 0.0);
  214.       pt[1] -= 25.0;
  215.    }
  216.  
  217.    cg_set_interior_style (EMPTY);
  218.    cg_open_structure ("S1");
  219.    cg_set_line_color (attributes.color);
  220.    cg_set_text_color (attributes.text_color);
  221.  
  222.    menu_highlighted = FALSE;
  223.    current_menu     = menu_number;
  224. }
  225. /**/
  226. void display_fixed_menu ()
  227.  
  228. {
  229.    int                       index;
  230.    t_world_coord             pt;
  231.    t_world_coord             text_pt;
  232.    t_world_coord             tmp_pt;
  233.  
  234.    cg_set_window ("FIXED VIEW", 1.0, 20.0);
  235.  
  236.    cg_inquire_view_transformation ("FIXED VIEW", viewport_ll, viewport_ur,
  237.                                     menu_ll, menu_ur);
  238.  
  239.    fixed_menu_center[0] = menu_ll[0];
  240.    fixed_menu_center[1] = menu_ll[1];
  241.  
  242.    pt[0] = menu_ll[0] + 25.0;
  243.    pt[1] = 1.0;
  244.  
  245.    cg_open_non_retained_structure ("FIXED MENU");
  246.  
  247.    cg_post_structure_to_view ("FIXED MENU", "FIXED VIEW");
  248.  
  249.    cg_set_text_color (WHITE);
  250.    cg_set_interior_style (FILL);
  251.    cg_set_line_style (SOLID);
  252.  
  253.    for (index = 0; index < 6; index++)
  254.    {
  255.       cg_set_line_color (BLACK);
  256.       tmp_pt[0] = pt[0] - 3.0;
  257.       tmp_pt[1] = pt[1] - 3.0;
  258.       cg_draw_rectangle (tmp_pt, 40.0, 15.0, 5.0, 0.0);
  259.       cg_set_line_color (RED);
  260.       cg_draw_rectangle (pt, 40.0, 15.0, 5.0, 0.0);
  261.       text_pt[0] = pt[0] - 15.0;
  262.       text_pt[1] = pt[1] - 3.0;
  263.       cg_draw_text (STRING_TEXT, text_pt, fixed_menu_items[index].item, 0.0, 0.0, 0.0);
  264.       pt[0] += 50.0;
  265.    }
  266.  
  267.    cg_set_interior_style (EMPTY);
  268. }
  269. /**/
  270. void display_color_menu ()
  271.  
  272. {
  273.    int                       color_index;
  274.    int                       i;
  275.    int                       j;
  276.    t_world_coord             pt;
  277.  
  278.    cg_set_window ("COLOR VIEW", 1.0, 20.0);
  279.  
  280.    cg_inquire_view_transformation ("COLOR VIEW", viewport_ll, viewport_ur,
  281.                                     menu_ll, menu_ur);
  282.  
  283.    pt[0] = menu_ll[0] + 5.0;
  284.    pt[1] = menu_ll[1] + 2.0;
  285.  
  286.    color_menu[0] = menu_ll[0];
  287.    color_menu[1] = menu_ll[1];
  288.  
  289.    cg_open_non_retained_structure ("COLOR MENU");
  290.  
  291.    cg_post_structure_to_view ("COLOR MENU", "COLOR VIEW");
  292.  
  293.    cg_set_interior_style (FILL);
  294.    cg_set_line_style (SOLID);
  295.  
  296.    color_index = 0;
  297.  
  298.    for (i = 0; i < 4; i++)
  299.    {
  300.       pt[0] = menu_ll[0] + 5.0;
  301.       for (j = 0; j < 4; j++)
  302.       {
  303.          cg_set_line_color (color_index);
  304.          cg_set_interior_style (FILL);
  305.          cg_draw_rectangle (pt, 6.0, 3.0, 0.0, 0.0);
  306.          cg_set_line_color (BLACK);
  307.          cg_set_interior_style (EMPTY);
  308.          cg_draw_rectangle (pt, 6.0, 3.0, 0.0, 0.0);
  309.          pt[0] += 8.0;
  310.          color_index++;
  311.       }
  312.       pt[1] += 5.0;
  313.    }
  314.  
  315.    cg_set_interior_style (EMPTY);
  316. }
  317. /**/
  318. int find_menu_picked ()
  319.  
  320. {
  321.    t_name_set                allowed_classes;
  322.    t_name_set                allowed_responses;
  323.  
  324.    cg_open_structure ("S1");
  325.    cg_set_element_identifier ((long) 0);
  326.  
  327.    while (TRUE)
  328.    {
  329.       if (!prompt_interrupted) 
  330.       {
  331.          allowed_classes   = 0;
  332.          allowed_responses = 0;
  333.          cg_add_name_to_set (&allowed_classes, LOCATE);
  334.  
  335.          cg_request_input (allowed_classes, allowed_responses,
  336.                            "Select menu item", &pick_buffer);
  337.       }
  338.  
  339.       prompt_interrupted = FALSE;
  340.  
  341.       if (check_menu_picked ())
  342.       {
  343.          if (menu_index > -1 )
  344.          {
  345.             if (menu_items[menu_index].next_menu != 0)
  346.                display_menu (menu_items[menu_index].next_menu);
  347.  
  348.             return (menu_items[menu_index].return_value);
  349.          }
  350.          else
  351.             if (fixed_index > -1)
  352.             {
  353.                process_fixed_menu ();
  354.                if (prompt_interrupted)
  355.                   return (FALSE);
  356.             }
  357.             else
  358.             {
  359.                prompt_interrupted = TRUE;
  360.                return (FALSE);
  361.             }
  362.       }
  363.    }
  364. }
  365. /**/
  366. bool check_menu_picked ()
  367.  
  368. {
  369.    int                       color_index;
  370.    int                       i;
  371.    int                       j;
  372.    t_world_coord             pt;
  373.  
  374.    menu_index  = -1;
  375.    fixed_index = -1;
  376.  
  377.    return_menu_item_selected = FALSE;
  378.  
  379.    if (strcmp (pick_buffer.view_name, "MENU VIEW") == 0)
  380.    {
  381.       pt[0] = menu_center[0] - 45.0;
  382.       pt[1] = menu_center[1] - 27.5;
  383.  
  384.       for (menu_index = menus[current_menu - 1];
  385.            menu_index < menus[current_menu]; menu_index++)
  386.       {
  387.          if (((pick_buffer.v.location[0] >= pt[0]) &&
  388.               (pick_buffer.v.location[0] <= (pt[0] + 90.0))) &&
  389.              ((pick_buffer.v.location[1] >= pt[1]) &&
  390.               (pick_buffer.v.location[1] <= (pt[1] + 15.0))))
  391.          {
  392.             cg_open_non_retained_structure ("MENU");
  393.             if (menu_highlighted)
  394.             {
  395.                cg_set_text_color (WHITE);
  396.                cg_draw_text (STRING_TEXT, menu_item_highlight_pt,
  397.                              menu_items[menu_highlight_item].item, 0.0, 0.0, 0.0);
  398.             }
  399.             menu_item_highlight_pt[0] = menu_center[0] - 40.0;
  400.             menu_item_highlight_pt[1] = pt[1] + 4.5;
  401.             cg_set_text_color (BLACK);
  402.             cg_draw_text (STRING_TEXT, menu_item_highlight_pt,
  403.                           menu_items[menu_index].item, 0.0, 0.0, 0.0);
  404.             menu_highlighted    = TRUE;
  405.             menu_highlight_item = menu_index;
  406.             cg_open_structure ("S1");
  407.  
  408.             return_menu_item_selected = strcmp (menu_items[menu_index].item, "Return") == 0;
  409.  
  410.             return (TRUE);
  411.          }
  412.  
  413.          pt[1] -= 25.0;
  414.       }
  415.    }
  416.    else
  417.       if (strcmp (pick_buffer.view_name, "FIXED VIEW") == 0)
  418.       {
  419.          pt[0] = fixed_menu_center[0];
  420.          pt[1] = fixed_menu_center[1];
  421.  
  422.          for (fixed_index = 0; fixed_index < 6; fixed_index++)
  423.          {
  424.             if (((pick_buffer.v.location[0] >= pt[0]) &&
  425.                  (pick_buffer.v.location[0] <= (pt[0] + 40.0))) &&
  426.                 ((pick_buffer.v.location[1] >= pt[1]) &&
  427.                  (pick_buffer.v.location[1] <= (pt[1] + 15.0))))
  428.                return (TRUE);
  429.  
  430.             pt[0] += 50.0;
  431.          }
  432.       }
  433.       else
  434.          if (strcmp (pick_buffer.view_name, "COLOR VIEW") == 0)
  435.          {
  436.             pt[0] = color_menu[0] + 2.0;
  437.             pt[1] = color_menu[1] + 0.5;
  438.      
  439.             color_index = 0;
  440.  
  441.             for (i = 0; i < 4; i++)
  442.             {
  443.                for (j = 0; j < 4; j++)
  444.                {
  445.                   if (((pick_buffer.v.location[0] >= pt[0]) &&
  446.                        (pick_buffer.v.location[0] <= (pt[0] + 6.0))) &&
  447.                       ((pick_buffer.v.location[1] >= pt[1]) &&
  448.                        (pick_buffer.v.location[1] <= (pt[1] + 3.0))))
  449.                   {
  450.                      cg_set_line_color (color_index);
  451.                      cg_set_text_color (color_index);
  452.                   }
  453.  
  454.                   pt[0] += 8.0;
  455.                   color_index++;
  456.                }
  457.                pt[0] = color_menu[0] + 2.0;
  458.                pt[1] += 5.0;
  459.             }
  460.          }
  461.  
  462.    return (FALSE);
  463. }
  464.  
  465. void process_fixed_menu ()
  466.  
  467. {
  468.    t_name_set                allowed_classes;
  469.    t_name_set                allowed_responses;
  470.    t_world_coord             tmp_pts[2];
  471.  
  472.    switch (fixed_menu_items[fixed_index].return_value)
  473.    {
  474.       case 101:                                         /* Zoom */
  475.          allowed_classes   = 0;
  476.          allowed_responses = 0;
  477.          cg_add_name_to_set (&allowed_classes, LOCATE);
  478.  
  479.          if (!valid_prompt (allowed_classes, allowed_responses,
  480.                             "Locate lower left corner of new window"))
  481.             return;
  482.  
  483.          tmp_pts[0][0] = pick_buffer.v.location[0];
  484.          tmp_pts[0][1] = pick_buffer.v.location[1];
  485.  
  486.          if (!valid_prompt (allowed_classes, allowed_responses,
  487.                             "Locate upper right corner of new window"))
  488.             return;
  489.  
  490.          tmp_pts[1][0] = pick_buffer.v.location[0];
  491.          tmp_pts[1][1] = pick_buffer.v.location[1];
  492.  
  493.          cg_zoom ("GRAPHIC VIEW", tmp_pts[0], tmp_pts[1]);
  494.  
  495.          cg_inquire_view_transformation ("GRAPHIC VIEW", viewport_ll, viewport_ur,
  496.                                          graphic_ll, graphic_ur);
  497.          break;
  498.  
  499.       case 102:                                         /* Pan */
  500.          allowed_classes   = 0;
  501.          allowed_responses = 0;
  502.          cg_add_name_to_set (&allowed_classes, LOCATE);
  503.          if (valid_prompt (allowed_classes, allowed_responses,
  504.                            "Locate new center of window"))
  505.          {
  506.             cg_pan ("GRAPHIC VIEW", pick_buffer.v.location);
  507.             cg_inquire_view_transformation ("GRAPHIC VIEW", viewport_ll, viewport_ur,
  508.                                             graphic_ll, graphic_ur);
  509.          }
  510.          break;
  511.  
  512.       case 103:                                         /* Full */
  513.          cg_set_window ("GRAPHIC VIEW", (real) 100.0, (real) 1.0);
  514.          break;
  515.  
  516.       case 104:                                         /* Save view */
  517.          cg_inquire_view_transformation ("GRAPHIC VIEW", viewport_ll,
  518.                                          viewport_ur, save_ll, save_ur);
  519.          break;
  520.  
  521.       case 105:                                         /* Restore view */
  522.          cg_zoom ("GRAPHIC VIEW", save_ll, save_ur);
  523.          break;
  524.  
  525.       case 106:                                         /* Clear */
  526.          allowed_classes   = 0;
  527.          allowed_responses = 0;
  528.          cg_add_name_to_set (&allowed_classes, STRING);
  529.          if (valid_prompt (allowed_classes, allowed_responses, "Erase drawing area?"))
  530.          {
  531.             if ((strcmp (pick_buffer.v.str, "Y") == 0) ||
  532.                 (strcmp (pick_buffer.v.str, "y") == 0))
  533.             {
  534.                element_id = 0;
  535.                cg_empty_structure ("S1");
  536.                cg_zoom ("GRAPHIC VIEW", graphic_ll, graphic_ur);
  537.             }
  538.          }
  539.          break;
  540.  
  541.       default:
  542.          break;
  543.    }
  544. }
  545.  
  546. bool process_point_menu (t_world_coord pt)
  547.  
  548. {
  549.    t_name_set                allowed_classes;
  550.    t_name_set                allowed_responses;
  551.    real                      dist1;
  552.    real                      dist2;
  553.    real                      dist3;
  554.    struct t_element          elem[2];
  555.    t_world_coord             mid_pt;
  556.    t_world_coord             tmp_pt[3];
  557.    real                      value;
  558.  
  559.    switch (menu_items[menu_index].return_value)
  560.    {
  561.       case 201:                                         /* Element */
  562.          allowed_classes   = 0;
  563.          allowed_responses = 0;
  564.          cg_add_name_to_set (&allowed_classes, PICK);
  565.          cg_add_all_names_to_set (&allowed_responses);
  566.          if (!valid_prompt (allowed_classes, allowed_responses,
  567.                            "Pick any element"))
  568.             return (FALSE);
  569.  
  570.          elem[0] = pick_buffer.v.pick.element;
  571.  
  572.          switch (elem[0].type)
  573.          {
  574.             case MARKER:
  575.                pt[0] = elem[0].v.marker.point[0];
  576.                pt[1] = elem[0].v.marker.point[1];
  577.                break;
  578.  
  579.             case LINE:
  580.                tmp_pt[0][0] = pick_buffer.v.pick.location[0];
  581.                tmp_pt[0][1] = pick_buffer.v.pick.location[1];
  582.                
  583.                cg_point_midpoint_line (elem[0].v.line.start_pt,
  584.                                        elem[0].v.line.end_pt, mid_pt);
  585.  
  586.                dist1 = cg_distance_between_2pts (elem[0].v.line.start_pt, tmp_pt[0]);
  587.                dist2 = cg_distance_between_2pts (elem[0].v.line.end_pt, tmp_pt[0]);
  588.                dist3 = cg_distance_between_2pts (mid_pt, tmp_pt[0]);
  589.  
  590.                if ((dist1 <= dist2) || (dist1 <= dist3))
  591.                {
  592.                   pt[0] = elem[0].v.line.start_pt[0];
  593.                   pt[1] = elem[0].v.line.start_pt[1];
  594.                }
  595.                else
  596.                   if (dist2 <= dist3)
  597.                   {
  598.                      pt[0] = elem[0].v.line.end_pt[0];
  599.                      pt[1] = elem[0].v.line.end_pt[1];
  600.                   }
  601.                   else
  602.                   {
  603.                      pt[0] = mid_pt[0];
  604.                      pt[1] = mid_pt[1];
  605.                   }
  606.                break;
  607.  
  608.             case CIRCLE:
  609.                pt[0] = elem[0].v.circle.center[0];
  610.                pt[1] = elem[1].v.circle.center[1];
  611.                break;
  612.  
  613.             case ARC:
  614.                break;
  615.  
  616.             default:
  617.                pt[0] = 0.0;
  618.                pt[1] = 0.0;
  619.                break;
  620.          }
  621.          break;
  622.  
  623.       case 202:                                         /* Around arc */
  624.          allowed_classes   = 0;
  625.          allowed_responses = 0;
  626.          cg_add_name_to_set (&allowed_classes, PICK);
  627.          cg_add_name_to_set (&allowed_responses, CIRCLE);
  628.  
  629.          if (!valid_prompt (allowed_classes, allowed_responses,
  630.                            "Pick arc or circle"))
  631.             return (FALSE);
  632.  
  633.          elem[0] = pick_buffer.v.pick.element;
  634.  
  635.          allowed_classes   = 0;
  636.          allowed_responses = 0;
  637.          cg_add_name_to_set (&allowed_classes, STRING);
  638.  
  639.          if (!valid_prompt (allowed_classes, allowed_responses,
  640.                             "Enter angle around arc"))
  641.             return (FALSE);
  642.  
  643.          value = atof (pick_buffer.v.str);
  644.  
  645.          cg_point_around_arc (elem[0].v.circle.center, elem[0].v.circle.radius,
  646.                               value, pt);
  647.          break;
  648.  
  649.       case 203:                                         /* Along line */
  650.          allowed_classes   = 0;
  651.          allowed_responses = 0;
  652.          cg_add_name_to_set (&allowed_classes, PICK);
  653.          cg_add_name_to_set (&allowed_responses, LINE);
  654.  
  655.          if (!valid_prompt (allowed_classes, allowed_responses,
  656.                            "Pick line near reference point"))
  657.             return (FALSE);
  658.  
  659.          elem[0]      = pick_buffer.v.pick.element;
  660.          tmp_pt[0][0] = pick_buffer.v.pick.location[0];
  661.          tmp_pt[0][1] = pick_buffer.v.pick.location[1];
  662.  
  663.          allowed_classes   = 0;
  664.          allowed_responses = 0;
  665.          cg_add_name_to_set (&allowed_classes, STRING);
  666.  
  667.          if (!valid_prompt (allowed_classes, allowed_responses,
  668.                             "Enter distance along line"))
  669.             return (FALSE);
  670.  
  671.          value = atof (pick_buffer.v.str);
  672.  
  673.          cg_point_along_line (elem[0].v.line.start_pt, elem[0].v.line.end_pt,
  674.                               value, tmp_pt[0], pt);
  675.          break;
  676.  
  677.       case 204:                                         /* Int 2 lines */
  678.          allowed_classes   = 0;
  679.          allowed_responses = 0;
  680.          cg_add_name_to_set (&allowed_classes, PICK);
  681.          cg_add_name_to_set (&allowed_responses, LINE);
  682.  
  683.          if (!valid_prompt (allowed_classes, allowed_responses,
  684.                                "Pick 1st line"))
  685.             return (FALSE);
  686.  
  687.          elem[0] = pick_buffer.v.pick.element;
  688.  
  689.          if (!valid_prompt (allowed_classes, allowed_responses,
  690.                             "Pick 2nd line"))
  691.             return (FALSE);
  692.  
  693.          elem[1] = pick_buffer.v.pick.element;
  694.  
  695.          if (!cg_intersect_2lines (elem[0].v.line.start_pt, elem[0].v.line.end_pt,
  696.                               elem[1].v.line.start_pt, elem[1].v.line.end_pt,
  697.                               pt))
  698.             return (FALSE);
  699.          break;
  700.  
  701.       case 205:                                         /* Int arc line */
  702.          allowed_classes   = 0;
  703.          cg_add_name_to_set (&allowed_classes, PICK);
  704.  
  705.          allowed_responses = 0;
  706.          cg_add_name_to_set (&allowed_responses, CIRCLE);
  707.  
  708.          if (!valid_prompt (allowed_classes, allowed_responses,
  709.                             "Pick circle near point of intersection"))
  710.             return (FALSE);
  711.  
  712.          elem[0]      = pick_buffer.v.pick.element;
  713.          tmp_pt[0][0] = pick_buffer.v.pick.location[0];
  714.          tmp_pt[0][1] = pick_buffer.v.pick.location[1];
  715.  
  716.          allowed_responses = 0;
  717.          cg_add_name_to_set (&allowed_responses, LINE);
  718.  
  719.          if (!valid_prompt (allowed_classes, allowed_responses,
  720.                             "Pick line"))
  721.             return (FALSE);
  722.  
  723.          elem[1] = pick_buffer.v.pick.element;
  724.  
  725.          if (!cg_intersect_arc_line (elem[0].v.circle.center, elem[0].v.circle.radius,
  726.                                      elem[1].v.line.start_pt, elem[1].v.line.end_pt,
  727.                                      tmp_pt[0], pt))
  728.             return (FALSE);
  729.          break;
  730.  
  731.       case 206:                                         /* Int 2 arcs */
  732.          allowed_classes   = 0;
  733.          allowed_responses = 0;
  734.          cg_add_name_to_set (&allowed_classes, PICK);
  735.          cg_add_name_to_set (&allowed_responses, CIRCLE);
  736.  
  737.          if (!valid_prompt (allowed_classes, allowed_responses,
  738.                             "Pick 1st circle near point of intersection"))
  739.             return (FALSE);
  740.  
  741.          elem[0]      = pick_buffer.v.pick.element;
  742.          tmp_pt[0][0] = pick_buffer.v.pick.location[0];
  743.          tmp_pt[0][1] = pick_buffer.v.pick.location[1];
  744.  
  745.          if (!valid_prompt (allowed_classes, allowed_responses,
  746.                             "Pick 2nd circle"))
  747.             return (FALSE);
  748.  
  749.          elem[1] = pick_buffer.v.pick.element;
  750.  
  751.          if (!cg_intersect_2arcs (elem[0].v.circle.center, elem[0].v.circle.radius,
  752.                                  elem[1].v.circle.center, elem[1].v.circle.radius,
  753.                                  tmp_pt[0], pt))
  754.             return (FALSE);
  755.          break;
  756.  
  757.       case 207:                                         /* Coordinate */
  758.          allowed_classes   = 0;
  759.          allowed_responses = 0;
  760.          cg_add_name_to_set (&allowed_classes, STRING);
  761.  
  762.          if (!valid_prompt (allowed_classes, allowed_responses,
  763.                             "Enter X coordinate"))
  764.             return (FALSE);
  765.  
  766.          pt[0] = atof (pick_buffer.v.str);
  767.  
  768.          if (!valid_prompt (allowed_classes, allowed_responses,
  769.                             "Enter Y coordinate"))
  770.             return (FALSE);
  771.  
  772.          pt[1] = atof (pick_buffer.v.str);
  773.          break;
  774.  
  775.       case 208:                                         /* Screen */
  776.          allowed_classes   = 0;
  777.          allowed_responses = 0;
  778.          cg_add_name_to_set (&allowed_classes, LOCATE);
  779.  
  780.          if (!valid_prompt (allowed_classes, allowed_responses,
  781.                             "Locate point"))
  782.             return (FALSE);
  783.  
  784.          pt[0] = pick_buffer.v.location[0];
  785.          pt[1] = pick_buffer.v.location[1];
  786.          break;
  787.  
  788.       case 209:                                         /* Return */
  789.          prompt_interrupted = TRUE;
  790.          return (FALSE);
  791.          break;
  792.    }
  793.  
  794.    return (TRUE);
  795. }
  796.  
  797. bool valid_prompt (t_name_set allowed_classes,
  798.                    t_name_set allowed_responses,
  799.                    char       *prompt)
  800.  
  801. {
  802.    t_name_set                local_allowed_classes;
  803.  
  804.    local_allowed_classes = allowed_classes;
  805.    cg_add_name_to_set (&local_allowed_classes, LOCATE);
  806.  
  807.    prompt_interrupted = FALSE;
  808.  
  809.    while (TRUE)
  810.    {
  811.       cg_request_input (local_allowed_classes, allowed_responses, prompt,
  812.                         &pick_buffer);
  813.       if (pick_buffer.type == STRING)
  814.          return (TRUE);
  815.       else
  816.          if (strcmp (pick_buffer.view_name, "GRAPHIC VIEW") == 0)
  817.             if (pick_buffer.type == LOCATE)
  818.             {   
  819.                 if (cg_inquire_name_set (allowed_classes, LOCATE))
  820.                   return (TRUE);
  821.             }
  822.             else
  823.                return (TRUE);
  824.          else
  825.             if (check_menu_picked ())
  826.             {
  827.                if (fixed_index > -1)
  828.                {
  829.                  process_fixed_menu ();
  830.                  if (prompt_interrupted)
  831.                     return (FALSE);
  832.                }
  833.                else
  834.                {
  835.                   if (current_menu == C_POINT_MENU)
  836.                   {
  837.                      if (!return_menu_item_selected)
  838.                      {
  839.                         default_point_menu[0] = pick_buffer.v.location[0];
  840.                         default_point_menu[1] = pick_buffer.v.location[1];
  841.                      }
  842.                   }
  843.  
  844.                   prompt_interrupted = TRUE;
  845.                   return (FALSE);
  846.                }
  847.             }
  848.    }
  849. }
  850.  
  851. bool get_point (bool          redisplay_menu,
  852.                 t_world_coord pt)
  853.  
  854. {
  855.    bool                      done;
  856.    bool                      return_value;
  857.  
  858.    prompt_interrupted = FALSE;
  859.  
  860.    display_menu (C_POINT_MENU);
  861.  
  862.    done = FALSE;
  863.  
  864.    while (!done)
  865.    {
  866.       pick_buffer.type          = LOCATE;
  867.       strcpy (pick_buffer.view_name, "MENU VIEW");
  868.       pick_buffer.v.location[0] = default_point_menu[0];
  869.       pick_buffer.v.location[1] = default_point_menu[1];
  870.  
  871.       check_menu_picked ();
  872.  
  873.       process_point_menu (pt);
  874.  
  875.       if (prompt_interrupted)
  876.       {
  877.          if (return_menu_item_selected)
  878.             done = TRUE;
  879.          return_value = FALSE;
  880.       }
  881.       else
  882.       {
  883.          done         = TRUE;
  884.          return_value = TRUE;
  885.       }
  886.    }
  887.  
  888.    if ((return_value == FALSE) || (redisplay_menu))
  889.    {
  890.       display_menu(save_current_menu);
  891.       prompt_interrupted = FALSE;
  892.    }
  893.  
  894.    return (return_value);
  895. }
  896.  
  897. /**/
  898. void display_about_cg_info ()
  899.  
  900. {
  901.    t_world_coord             pt;
  902.  
  903.    cg_set_structure_visibility ("S1", OFF);
  904.  
  905.    cg_open_structure ("INFO");
  906.  
  907.    cg_post_structure_to_view ("INFO", "GRAPHIC VIEW");
  908.  
  909.    cg_set_text_color (WHITE);
  910.  
  911.    pt[0] = graphic_ll[0] + 10.0;
  912.    pt[1] = graphic_ur[0] - 10.0;
  913.  
  914.    for (i = 0; i < 15; i++)
  915.    {
  916.       cg_draw_text (STRING_TEXT, pt, intro[i], 0.0, 0.0, 0.0);
  917.       pt[1] -= 5.0;
  918.    }
  919.  
  920.    if (find_menu_picked () == C_CONTINUE)
  921.    {
  922.       cg_open_structure  ("INFO");
  923.       cg_empty_structure ("INFO");
  924.  
  925.       cg_set_text_color (WHITE);
  926.  
  927.       pt[0] = graphic_ll[0] + 10.0;
  928.       pt[1] = graphic_ur[0] - 10.0;
  929.  
  930.       for (i = 15; i < 26; i++)
  931.       {
  932.          cg_draw_text (STRING_TEXT, pt, intro[i], 0.0, 0.0, 0.0);
  933.          pt[1] -= 5.0;
  934.       }
  935.  
  936.       if (find_menu_picked () == C_CONTINUE)
  937.       {
  938.          display_menu (3);
  939.  
  940.          cg_open_structure  ("INFO");
  941.          cg_empty_structure ("INFO");
  942.  
  943.          cg_set_text_color (WHITE);
  944.     
  945.          pt[0] = graphic_ll[0] + 10.0;
  946.          pt[1] = graphic_ur[0] - 10.0;
  947.  
  948.          for (i = 26; i < 33; i++)
  949.          {
  950.             cg_draw_text (STRING_TEXT, pt, intro[i], 0.0, 0.0, 0.0);
  951.             pt[1] -= 5.0;
  952.          }
  953.  
  954.          find_menu_picked ();
  955.       }
  956.    }
  957.  
  958.    cg_delete_structure ("INFO");
  959.  
  960.    cg_set_structure_visibility ("S1", ON);
  961. }
  962.  
  963. void point ()
  964.  
  965. {
  966.    save_current_menu = current_menu;
  967.  
  968.    while (TRUE)
  969.    {
  970.       if (!get_point (FALSE, pts[0]))
  971.           return;
  972.  
  973.       cg_set_element_identifier (element_id++);
  974.       cg_draw_marker (PLUS, pts[0]);
  975.    }
  976.  
  977.    display_menu (save_current_menu);
  978. }
  979.  
  980. void delete_element ()
  981.  
  982. {
  983.    t_name_set                allowed_classes;
  984.    t_name_set                allowed_responses;
  985.  
  986.    while (TRUE)
  987.    {
  988.       allowed_classes   = 0;
  989.       allowed_responses = 0;
  990.       cg_add_name_to_set (&allowed_classes, PICK);
  991.       cg_add_all_names_to_set (&allowed_responses);
  992.  
  993.       if (!valid_prompt (allowed_classes, allowed_responses, "Pick element to delete"))
  994.          return;
  995.  
  996.       cg_delete_element ("S1", pick_buffer.v.pick.element.id);
  997.    }
  998. }
  999.  
  1000. void line_2pts ()
  1001.  
  1002. {
  1003.    save_current_menu = current_menu;
  1004.  
  1005.    while (TRUE)
  1006.    {
  1007.       if (!get_point (FALSE, pts[0]))
  1008.           return;
  1009.  
  1010.       if (!get_point (TRUE, pts[1]))
  1011.            return;
  1012.  
  1013.       cg_set_element_identifier (element_id++);
  1014.       cg_draw_line (pts[0], pts[1]);
  1015.    }
  1016.  
  1017.    display_menu (save_current_menu);
  1018. }
  1019.  
  1020. void line_pt_angle_distance (real angle)
  1021.  
  1022. {
  1023.    t_name_set                allowed_classes;
  1024.    t_name_set                allowed_responses;
  1025.    real                      distance;
  1026.    t_world_coord             end_pt;
  1027.  
  1028.    save_current_menu = current_menu;
  1029.  
  1030.    while (TRUE)
  1031.    {
  1032.       if (!get_point (FALSE, pts[0]))
  1033.           return;
  1034.  
  1035.       allowed_classes   = 0;
  1036.       allowed_responses = 0;
  1037.       cg_add_name_to_set (&allowed_classes, STRING);
  1038.  
  1039.       if (!valid_prompt (allowed_classes, allowed_responses, "Enter distance"))
  1040.          return;
  1041.  
  1042.       distance = atof (pick_buffer.v.str);
  1043.  
  1044.       if (angle == (real) 0.0)
  1045.       {
  1046.          end_pt[0] = pts[0][0] + distance;
  1047.          end_pt[1] = pts[0][1];
  1048.       }
  1049.       else
  1050.       {
  1051.          end_pt[0] = pts[0][0];
  1052.          end_pt[1] = pts[0][1] + distance;
  1053.       }
  1054.  
  1055. //      cg_line_pt_angle_distance (pts[0], angle, distance, end_pt);
  1056.  
  1057.       cg_set_element_identifier (element_id++);
  1058.       cg_draw_line (pts[0], end_pt);
  1059.    }
  1060.  
  1061.    display_menu (save_current_menu);
  1062. }
  1063.  
  1064. void line_parallel ()
  1065.  
  1066. {
  1067.    t_name_set                allowed_classes;
  1068.    t_name_set                allowed_responses;
  1069.    struct t_element          elem[1];
  1070.    t_world_coord             new_start_pt;
  1071.    t_world_coord             new_end_pt;
  1072.  
  1073.    allowed_classes   = 0;
  1074.    allowed_responses = 0;
  1075.    cg_add_name_to_set (&allowed_classes, PICK);
  1076.    cg_add_name_to_set (&allowed_responses, LINE);
  1077.  
  1078.    if (!valid_prompt (allowed_classes, allowed_responses,
  1079.                       "Pick line"))
  1080.      return;
  1081.  
  1082.    elem[0] = pick_buffer.v.pick.element;
  1083.  
  1084.    allowed_classes   = 0;
  1085.    allowed_responses = 0;
  1086.    cg_add_name_to_set (&allowed_classes, STRING);
  1087.  
  1088.    while (TRUE)
  1089.    {
  1090.  
  1091.       if (!valid_prompt (allowed_classes, allowed_responses, "Enter distance"))
  1092.          return;
  1093.  
  1094.       distance = atof (pick_buffer.v.str);
  1095.  
  1096.       cg_line_parallel (elem[0].v.line.start_pt, elem[0].v.line.end_pt,
  1097.                         distance, new_start_pt, new_end_pt);
  1098.  
  1099.       cg_set_element_identifier (element_id++);
  1100.       cg_draw_line (new_start_pt, new_end_pt);
  1101.    }
  1102. }
  1103.  
  1104. void line_perpendicular ()
  1105.  
  1106. {
  1107.    t_name_set                allowed_classes;
  1108.    t_name_set                allowed_responses;
  1109.    struct t_element          elem[1];
  1110.    t_world_coord             new_pt;
  1111.  
  1112.    allowed_classes   = 0;
  1113.    allowed_responses = 0;
  1114.    cg_add_name_to_set (&allowed_classes, PICK);
  1115.    cg_add_name_to_set (&allowed_responses, LINE);
  1116.  
  1117.    if (!valid_prompt (allowed_classes, allowed_responses,
  1118.                       "Pick line"))
  1119.      return;
  1120.  
  1121.    elem[0] = pick_buffer.v.pick.element;
  1122.  
  1123.    allowed_classes   = 0;
  1124.    allowed_responses = 0;
  1125.    cg_add_name_to_set (&allowed_classes, LOCATE);
  1126.  
  1127.    while (TRUE)
  1128.    {
  1129.       if (!get_point (TRUE, pts[0]))
  1130.          return;
  1131.  
  1132.       cg_line_perpendicular (pts[0],
  1133.                              elem[0].v.line.start_pt, elem[0].v.line.end_pt,
  1134.                              new_pt);
  1135.  
  1136.       cg_set_element_identifier (element_id++);
  1137.       cg_draw_line (pts[0], new_pt);
  1138.    }
  1139. }
  1140.  
  1141. void line_tan_arc ()
  1142.  
  1143. {
  1144.    t_name_set                allowed_classes;
  1145.    t_name_set                allowed_responses;
  1146.    struct t_element          elem[1];
  1147.    t_world_coord             new_end_pt;
  1148.  
  1149.    save_current_menu = current_menu;
  1150.  
  1151.    while (TRUE)
  1152.    {
  1153.       allowed_classes   = 0;
  1154.       allowed_responses = 0;
  1155.       cg_add_name_to_set (&allowed_classes, PICK);
  1156.       cg_add_name_to_set (&allowed_responses, CIRCLE);
  1157.     
  1158.       if (!valid_prompt (allowed_classes, allowed_responses,
  1159.                          "Pick circle near point of tangency"))
  1160.         return;
  1161.  
  1162.       elem[0]   = pick_buffer.v.pick.element;
  1163.       pts[0][0] = pick_buffer.v.pick.location[0];
  1164.       pts[0][1] = pick_buffer.v.pick.location[1];
  1165.  
  1166.       allowed_classes   = 0;
  1167.       allowed_responses = 0;
  1168.       cg_add_name_to_set (&allowed_classes, LOCATE);
  1169.  
  1170.       if (!get_point (TRUE, pts[1]))
  1171.          return;
  1172.  
  1173.       cg_line_tan_arc (pts[1], elem[0].v.circle.center,
  1174.                        elem[0].v.circle.radius, pts[0], new_end_pt);
  1175.  
  1176.       cg_set_element_identifier (element_id++);
  1177.       cg_draw_line (pick_buffer.v.location, new_end_pt);
  1178.    }
  1179.  
  1180.    display_menu (save_current_menu);
  1181. }
  1182.  
  1183. void line_tan_2arcs ()
  1184.  
  1185. {
  1186.    t_name_set                allowed_classes;
  1187.    t_name_set                allowed_responses;
  1188.    struct t_element          elem[2];
  1189.    t_world_coord             line_start_pt;
  1190.    t_world_coord             line_end_pt;
  1191.  
  1192.    while (TRUE)
  1193.    {
  1194.       allowed_classes   = 0;
  1195.       allowed_responses = 0;
  1196.       cg_add_name_to_set (&allowed_classes, PICK);
  1197.       cg_add_name_to_set (&allowed_responses, CIRCLE);
  1198.     
  1199.       if (!valid_prompt (allowed_classes, allowed_responses,
  1200.                          "Pick 1st circle near point of tangency"))
  1201.         return;
  1202.  
  1203.       elem[0]   = pick_buffer.v.pick.element;
  1204.       pts[0][0] = pick_buffer.v.pick.location[0];
  1205.       pts[0][1] = pick_buffer.v.pick.location[1];
  1206.  
  1207.       if (!valid_prompt (allowed_classes, allowed_responses,
  1208.                          "Pick 2nd circle near point of tangency"))
  1209.         return;
  1210.  
  1211.       elem[1]   = pick_buffer.v.pick.element;
  1212.       pts[1][0] = pick_buffer.v.pick.location[0];
  1213.       pts[1][1] = pick_buffer.v.pick.location[1];
  1214.  
  1215.       cg_line_tan_2arcs (elem[0].v.circle.center, elem[0].v.circle.radius,
  1216.                          elem[1].v.circle.center, elem[1].v.circle.radius,
  1217.                          pts[0], pts[1], line_start_pt, line_end_pt);
  1218.  
  1219.       cg_set_element_identifier (element_id++);
  1220.       cg_draw_line (line_start_pt, line_end_pt);
  1221.    }
  1222. }
  1223.  
  1224. void circle_3pts ()
  1225.  
  1226. {
  1227.    t_world_coord             center;
  1228.    real                      radius;
  1229.  
  1230.    save_current_menu = current_menu;
  1231.  
  1232.    while (TRUE)
  1233.    {
  1234.       cg_set_element_identifier ((long) 9999);
  1235.  
  1236.       if (!get_point (FALSE, pts[0]))
  1237.          return;
  1238.  
  1239.       cg_draw_marker (PLUS, pts[0]);
  1240.  
  1241.       if (!get_point (FALSE, pts[1]))
  1242.          return;
  1243.  
  1244.       cg_draw_marker (PLUS, pts[1]);
  1245.  
  1246.       if (!get_point (TRUE, pts[2]))
  1247.          return;
  1248.  
  1249.       cg_draw_marker (PLUS, pts[2]);
  1250.  
  1251.       cg_set_element_identifier ((long) 0);
  1252.  
  1253.       cg_delete_element ("S1", (long) 9999);
  1254.  
  1255.       if (cg_circle_3pts (pts[0], pts[1], pts[2], center, &radius))
  1256.       {
  1257.          cg_set_element_identifier (element_id++);
  1258.          cg_draw_circle (center, radius);
  1259.       }
  1260.    }
  1261.  
  1262.    display_menu (save_current_menu);
  1263. }
  1264.  
  1265. void circle_tan_line_pt ()
  1266.  
  1267. {
  1268.    t_name_set                allowed_classes;
  1269.    t_name_set                allowed_responses;
  1270.    t_world_coord             center;
  1271.    struct t_element          elem[2];
  1272.    real                      radius;
  1273.  
  1274.    save_current_menu = current_menu;
  1275.  
  1276.    while (TRUE)
  1277.    {
  1278.       allowed_classes   = 0;
  1279.       allowed_responses = 0;
  1280.       cg_add_name_to_set (&allowed_classes, PICK);
  1281.       cg_add_name_to_set (&allowed_responses, LINE);
  1282.  
  1283.       if (!valid_prompt (allowed_classes, allowed_responses,
  1284.                          "Pick line"))
  1285.          return;
  1286.  
  1287.       elem[0] = pick_buffer.v.pick.element;
  1288.  
  1289.       if (!get_point (TRUE, pts[0]))
  1290.          return;
  1291.  
  1292.       allowed_classes   = 0;
  1293.       allowed_responses = 0;
  1294.       cg_add_name_to_set (&allowed_classes, STRING);
  1295.  
  1296.       if (!valid_prompt (allowed_classes, allowed_responses, "Enter radius"))
  1297.          return;
  1298.  
  1299.       radius = atof (pick_buffer.v.str);
  1300.  
  1301.       allowed_classes   = 0;
  1302.       allowed_responses = 0;
  1303.       cg_add_name_to_set (&allowed_classes, LOCATE);
  1304.  
  1305.       if (!valid_prompt (allowed_classes, allowed_responses,
  1306.                          "Locate point near center of circle"))
  1307.          return;
  1308.  
  1309.       pts[1][0] = pick_buffer.v.location[0];
  1310.       pts[1][1] = pick_buffer.v.location[1];
  1311.  
  1312.       if (cg_circle_tan_line_pt_radius (elem[0].v.line.start_pt, elem[0].v.line.end_pt,
  1313.                                         pts[0], radius, pts[1], center))
  1314.       {
  1315.          cg_set_element_identifier (element_id++);
  1316.          cg_draw_circle (center, radius);
  1317.       }
  1318.    }
  1319.  
  1320.    display_menu (save_current_menu);
  1321. }
  1322.  
  1323. void circle_tan_line_2pts ()
  1324.  
  1325. {
  1326.    t_name_set                allowed_classes;
  1327.    t_name_set                allowed_responses;
  1328.    t_world_coord             center;
  1329.    struct t_element          elem[2];
  1330.    real                      radius;
  1331.  
  1332.    save_current_menu = current_menu;
  1333.  
  1334.    while (TRUE)
  1335.    {
  1336.       allowed_classes   = 0;
  1337.       allowed_responses = 0;
  1338.       cg_add_name_to_set (&allowed_classes, PICK);
  1339.       cg_add_name_to_set (&allowed_responses, LINE);
  1340.  
  1341.       if (!valid_prompt (allowed_classes, allowed_responses,
  1342.                          "Pick line"))
  1343.          return;
  1344.  
  1345.       elem[0] = pick_buffer.v.pick.element;
  1346.  
  1347.       if (!get_point (FALSE, pts[0]))
  1348.          return;
  1349.  
  1350.       if (!get_point (TRUE, pts[1]))
  1351.          return;
  1352.  
  1353.       allowed_classes   = 0;
  1354.       allowed_responses = 0;
  1355.       cg_add_name_to_set (&allowed_classes, LOCATE);
  1356.  
  1357.       if (!valid_prompt (allowed_classes, allowed_responses,
  1358.                          "Locate point near center of circle"))
  1359.          return;
  1360.  
  1361.       pts[2][0] = pick_buffer.v.location[0];
  1362.       pts[2][1] = pick_buffer.v.location[1];
  1363.  
  1364.       if (cg_circle_tan_line_2pts (elem[0].v.line.start_pt, elem[0].v.line.end_pt,
  1365.                                    pts[0], pts[1], pts[2], center, &radius))
  1366.       {
  1367.          cg_set_element_identifier (element_id++);
  1368.          cg_draw_circle (center, radius);
  1369.       }
  1370.    }
  1371.  
  1372.    display_menu (save_current_menu);
  1373. }
  1374.  
  1375. void circle_tan_2lines ()
  1376.  
  1377. {
  1378.    t_name_set                allowed_classes;
  1379.    t_name_set                allowed_responses;
  1380.    t_world_coord             center;
  1381.    struct t_element          elem[2];
  1382.    real                      radius;
  1383.  
  1384.    while (TRUE)
  1385.    {
  1386.       allowed_classes   = 0;
  1387.       allowed_responses = 0;
  1388.       cg_add_name_to_set (&allowed_classes, PICK);
  1389.       cg_add_name_to_set (&allowed_responses, LINE);
  1390.  
  1391.       if (!valid_prompt (allowed_classes, allowed_responses,
  1392.                          "Pick 1st line"))
  1393.          return;
  1394.  
  1395.       elem[0]   = pick_buffer.v.pick.element;
  1396.  
  1397.       if (!valid_prompt (allowed_classes, allowed_responses,
  1398.                          "Pick 2st line"))
  1399.          return;
  1400.  
  1401.       elem[1]   = pick_buffer.v.pick.element;
  1402.  
  1403.       allowed_classes   = 0;
  1404.       allowed_responses = 0;
  1405.       cg_add_name_to_set (&allowed_classes, LOCATE);
  1406.  
  1407.       if (!valid_prompt (allowed_classes, allowed_responses,
  1408.                          "Locate side for circle"))
  1409.          return;
  1410.  
  1411.       pts[0][0] = pick_buffer.v.location[0];
  1412.       pts[0][1] = pick_buffer.v.location[1];
  1413.  
  1414.       allowed_classes   = 0;
  1415.       allowed_responses = 0;
  1416.       cg_add_name_to_set (&allowed_classes, STRING);
  1417.  
  1418.       if (!valid_prompt (allowed_classes, allowed_responses, "Enter radius"))
  1419.          return;
  1420.  
  1421.       radius = atof (pick_buffer.v.str);
  1422.  
  1423.       if (cg_circle_tan_2lines_radius (elem[0].v.line.start_pt, elem[0].v.line.end_pt,
  1424.                                        elem[1].v.line.start_pt, elem[1].v.line.end_pt,
  1425.                                        radius, pts[0], center))
  1426.       {
  1427.          cg_set_element_identifier (element_id++);
  1428.          cg_draw_circle (center, radius);
  1429.       }
  1430.    }
  1431. }
  1432.  
  1433. void circle_tan_2lines_pt ()
  1434.  
  1435. {
  1436.    t_name_set                allowed_classes;
  1437.    t_name_set                allowed_responses;
  1438.    t_world_coord             center;
  1439.    struct t_element          elem[2];
  1440.    real                      radius;
  1441.  
  1442.    save_current_menu = current_menu;
  1443.  
  1444.    while (TRUE)
  1445.    {
  1446.       allowed_classes   = 0;
  1447.       allowed_responses = 0;
  1448.       cg_add_name_to_set (&allowed_classes, PICK);
  1449.       cg_add_name_to_set (&allowed_responses, LINE);
  1450.  
  1451.       if (!valid_prompt (allowed_classes, allowed_responses,
  1452.                          "Pick 1st line"))
  1453.          return;
  1454.  
  1455.       elem[0] = pick_buffer.v.pick.element;
  1456.  
  1457.       if (!valid_prompt (allowed_classes, allowed_responses,
  1458.                          "Pick 2st line"))
  1459.          return;
  1460.  
  1461.       elem[1] = pick_buffer.v.pick.element;
  1462.  
  1463.       if (!get_point (TRUE, pts[0]))
  1464.          return;
  1465.  
  1466.       allowed_classes   = 0;
  1467.       allowed_responses = 0;
  1468.       cg_add_name_to_set (&allowed_classes, LOCATE);
  1469.  
  1470.       if (!valid_prompt (allowed_classes, allowed_responses,
  1471.                        "Locate side for circle"))
  1472.          return;
  1473.  
  1474.       pts[1][0] = pick_buffer.v.location[0];
  1475.       pts[1][1] = pick_buffer.v.location[1];
  1476.  
  1477.       if (cg_circle_tan_2lines_pt (elem[0].v.line.start_pt, elem[0].v.line.end_pt,
  1478.                                    elem[1].v.line.start_pt, elem[1].v.line.end_pt,
  1479.                                    pts[0], pts[1], center, &radius))
  1480.       {
  1481.          cg_set_element_identifier (element_id++);
  1482.          cg_draw_circle (center, radius);
  1483.       }
  1484.    }
  1485.  
  1486.    display_menu (save_current_menu);
  1487. }
  1488.  
  1489. void circle_tan_3lines ()
  1490.  
  1491. {
  1492.    t_name_set                allowed_classes;
  1493.    t_name_set                allowed_responses;
  1494.    t_world_coord             center;
  1495.    struct t_element          elem[3];
  1496.    real                      radius;
  1497.  
  1498.    allowed_classes   = 0;
  1499.    allowed_responses = 0;
  1500.    cg_add_name_to_set (&allowed_classes, PICK);
  1501.    cg_add_name_to_set (&allowed_responses, LINE);
  1502.  
  1503.    while (TRUE)
  1504.    {
  1505.       if (!valid_prompt (allowed_classes, allowed_responses,
  1506.                          "Pick 1st line"))
  1507.          return;
  1508.  
  1509.       elem[0] = pick_buffer.v.pick.element;
  1510.  
  1511.       if (!valid_prompt (allowed_classes, allowed_responses,
  1512.                          "Pick 2nd line"))
  1513.          return;
  1514.  
  1515.       elem[1] = pick_buffer.v.pick.element;
  1516.  
  1517.       if (!valid_prompt (allowed_classes, allowed_responses,
  1518.                          "Pick 3rd line"))
  1519.          return;
  1520.  
  1521.       elem[2] = pick_buffer.v.pick.element;
  1522.  
  1523.       if (cg_intersect_2lines (elem[0].v.line.start_pt, elem[0].v.line.end_pt,
  1524.                                elem[1].v.line.start_pt, elem[1].v.line.end_pt,
  1525.                                pts[0]) &&
  1526.           cg_intersect_2lines (elem[0].v.line.start_pt, elem[0].v.line.end_pt,
  1527.                                elem[2].v.line.start_pt, elem[2].v.line.end_pt,
  1528.                                pts[1]) &&
  1529.           cg_intersect_2lines (elem[1].v.line.start_pt, elem[1].v.line.end_pt,
  1530.                                elem[2].v.line.start_pt, elem[2].v.line.end_pt,
  1531.                                pts[2]))
  1532.       {
  1533.          cg_circle_tan_3lines (pts[1], pts[0], pts[2], center, &radius);
  1534.      
  1535.          cg_set_element_identifier (element_id++);
  1536.          cg_draw_circle (center, radius);
  1537.       }
  1538.    }
  1539. }
  1540.  
  1541. void circle_tan_2arcs ()
  1542.  
  1543. {
  1544.    t_name_set                allowed_classes;
  1545.    t_name_set                allowed_responses;
  1546.    struct t_element          elem[2];
  1547.    t_world_coord             new_center;
  1548.    real                      radius;
  1549.  
  1550.    while (TRUE)
  1551.    {
  1552.       allowed_classes   = 0;
  1553.       allowed_responses = 0;
  1554.       cg_add_name_to_set (&allowed_classes, PICK);
  1555.       cg_add_name_to_set (&allowed_responses, CIRCLE);
  1556.  
  1557.       for (i = 0; i < 2; i++)
  1558.       {
  1559.         if (!valid_prompt (allowed_classes, allowed_responses, "Pick circle"))
  1560.            return;
  1561.  
  1562.         elem[i] = pick_buffer.v.pick.element;
  1563.       }
  1564.  
  1565.       allowed_classes   = 0;
  1566.       allowed_responses = 0;
  1567.       cg_add_name_to_set (&allowed_classes, LOCATE);
  1568.  
  1569.       if (!valid_prompt (allowed_classes, allowed_responses, 
  1570.                          "Locate side for circle"))
  1571.          return;
  1572.  
  1573.       pts[0][0] = pick_buffer.v.location[0];
  1574.       pts[0][1] = pick_buffer.v.location[1];
  1575.  
  1576.       allowed_classes   = 0;
  1577.       allowed_responses = 0;
  1578.       cg_add_name_to_set (&allowed_classes, STRING);
  1579.  
  1580.       if (!valid_prompt (allowed_classes, allowed_responses, "Enter radius"))
  1581.          return;
  1582.  
  1583.       radius = atof (pick_buffer.v.str);
  1584.  
  1585.       if (cg_circle_tan_2arcs_radius (elem[0].v.circle.center, elem[0].v.circle.radius,
  1586.                                       elem[1].v.circle.center, elem[1].v.circle.radius,
  1587.                                       radius, pts[0], new_center))
  1588.       {      
  1589.          cg_set_element_identifier (element_id++);
  1590.          cg_draw_circle (new_center, radius);
  1591.       }
  1592.    }
  1593. }
  1594.  
  1595. void circle_tan_arc_line ()
  1596.  
  1597. {
  1598.    t_name_set                allowed_classes;
  1599.    t_name_set                allowed_responses;
  1600.    struct t_element          elem[3];
  1601.    t_world_coord             new_center;
  1602.    real                      radius;
  1603.  
  1604.    while (TRUE)
  1605.    {
  1606.       allowed_classes   = 0;
  1607.       allowed_responses = 0;
  1608.       cg_add_name_to_set (&allowed_classes, PICK);
  1609.       cg_add_name_to_set (&allowed_responses, CIRCLE);
  1610.  
  1611.       if (!valid_prompt (allowed_classes, allowed_responses, "Pick circle"))
  1612.          return;
  1613.  
  1614.       elem[0] = pick_buffer.v.pick.element;
  1615.  
  1616.       allowed_responses = 0;
  1617.       cg_add_name_to_set (&allowed_responses, LINE);
  1618.  
  1619.       if (!valid_prompt (allowed_classes, allowed_responses,
  1620.                          "Pick line"))
  1621.          return;
  1622.  
  1623.       elem[1]   = pick_buffer.v.pick.element;
  1624.  
  1625.       allowed_classes   = 0;
  1626.       allowed_responses = 0;
  1627.       cg_add_name_to_set (&allowed_classes, LOCATE);
  1628.  
  1629.       if (!valid_prompt (allowed_classes, allowed_responses, 
  1630.                          "Locate side for circle"))
  1631.          return;
  1632.  
  1633.       pts[0][0] = pick_buffer.v.location[0];
  1634.       pts[0][1] = pick_buffer.v.location[1];
  1635.  
  1636.       allowed_classes   = 0;
  1637.       allowed_responses = 0;
  1638.       cg_add_name_to_set (&allowed_classes, STRING);
  1639.  
  1640.       if (!valid_prompt (allowed_classes, allowed_responses, "Enter radius"))
  1641.          return;
  1642.  
  1643.       radius = atof (pick_buffer.v.str);
  1644.  
  1645.       if (cg_circle_tan_arc_line_radius (elem[0].v.circle.center,
  1646.                                          elem[0].v.circle.radius,
  1647.                                          elem[1].v.line.start_pt,
  1648.                                          elem[1].v.line.end_pt,
  1649.                                          radius, pts[0],
  1650.                                          new_center))
  1651.       {
  1652.          cg_set_element_identifier (element_id++);
  1653.          cg_draw_circle (new_center, radius);
  1654.       }
  1655.    }
  1656. }
  1657.  
  1658. void main ()
  1659.  
  1660. {
  1661.    bool                      done;
  1662.  
  1663.    cg_initialize ();
  1664.    cg_inquire_workstation (&device_params);
  1665.  
  1666.    cg_set_line_color (RED);
  1667.    cg_set_line_style (SOLID);
  1668.  
  1669.    viewport_ll[0] = 0.0;
  1670.    viewport_ll[1] = 0.15;
  1671.    viewport_ur[0] = 0.25;
  1672.    viewport_ur[1] = device_params.aspect_ratio;
  1673.  
  1674.    cg_open_view ("MENU VIEW", viewport_ll, viewport_ur, LIGHT_GRAY, NO_BORDER);
  1675.  
  1676.    cg_inquire_view_transformation ("MENU VIEW", viewport_ll, viewport_ur,
  1677.                                     menu_ll, menu_ur);
  1678.  
  1679.    menu_center[0] = menu_ll[0] + 50.0;
  1680.    menu_center[1] = menu_ur[1];
  1681.  
  1682.    cg_open_non_retained_structure ("MENU");
  1683.    cg_post_structure_to_view ("MENU", "MENU VIEW");
  1684.  
  1685.    viewport_ll[0] = 0.25;
  1686.    viewport_ll[1] = 0.0;
  1687.    viewport_ur[0] = 1.0;
  1688.    viewport_ur[1] = 0.05;
  1689.  
  1690.    cg_open_view ("FIXED VIEW", viewport_ll, viewport_ur, LIGHT_GRAY, NO_BORDER);
  1691.  
  1692.    viewport_ll[0] = 0.0;
  1693.    viewport_ll[1] = 0.0;
  1694.    viewport_ur[0] = 0.25;
  1695.    viewport_ur[1] = 0.15;
  1696.  
  1697.    cg_open_view ("COLOR VIEW", viewport_ll, viewport_ur, LIGHT_GRAY, NO_BORDER);
  1698.  
  1699.    viewport_ll[0] = 0.25;
  1700.    viewport_ll[1] = 0.05;
  1701.    viewport_ur[0] = 1.0;
  1702.    viewport_ur[1] = device_params.aspect_ratio - 0.05;
  1703.  
  1704.    cg_open_view ("GRAPHIC VIEW", viewport_ll, viewport_ur, CYAN, NO_BORDER);
  1705.  
  1706.    cg_inquire_view_transformation ("GRAPHIC VIEW", viewport_ll, viewport_ur,
  1707.                                     graphic_ll, graphic_ur);
  1708.  
  1709.    cg_inquire_view_transformation ("GRAPHIC VIEW", viewport_ll,
  1710.                                    viewport_ur, save_ll, save_ur);
  1711.  
  1712.    viewport_ll[0] = 0.25;
  1713.    viewport_ll[1] = device_params.aspect_ratio - 0.05;
  1714.    viewport_ur[0] = 1.0;
  1715.    viewport_ur[1] = device_params.aspect_ratio;
  1716.  
  1717.    cg_open_view ("TITLE VIEW", viewport_ll, viewport_ur, LIGHT_GRAY, NO_BORDER);
  1718.  
  1719.    cg_open_non_retained_structure ("S2");
  1720.    cg_post_structure_to_view ("S2", "TITLE VIEW");
  1721.  
  1722.    text_ll[0] = -45.0;
  1723.    text_ll[1] = -1.0;
  1724.  
  1725.    cg_set_text_color (BLACK);
  1726.  
  1727.    cg_draw_text (STRING_TEXT, text_ll, 
  1728.                  "CommonGeometry (v 1.0)  Copyright 1993 Rialto Software",
  1729.                  0.0, 0.0, 0.0);
  1730.  
  1731.    viewport_ll[0] = 0.26;
  1732.    viewport_ll[1] = 0.06;
  1733.  
  1734.    cg_set_string_response (viewport_ll, BLACK, CYAN);
  1735.  
  1736.    cg_open_structure ("S1");
  1737.    cg_post_structure_to_view ("S1", "GRAPHIC VIEW");
  1738.  
  1739.    display_menu (1);
  1740.    display_fixed_menu ();
  1741.    display_color_menu ();
  1742.  
  1743.    cg_set_line_color (RED);
  1744.    cg_set_text_color (RED);
  1745.  
  1746.    default_point_menu[0] = (real) -14.945227;              /* Element */
  1747.    default_point_menu[1] = (real) 109.290199;
  1748.  
  1749.    done               = FALSE;
  1750.    element_id         = 0;
  1751.    prompt_interrupted = TRUE;
  1752.  
  1753.    while (!done)
  1754.    {
  1755.       switch (find_menu_picked ())
  1756.       {
  1757.          case 0:
  1758.             break;
  1759.  
  1760.          case 1:
  1761.             display_about_cg_info ();
  1762.             break;
  1763.  
  1764.          case 2:
  1765.             done = TRUE;
  1766.             break;
  1767.  
  1768.          case 3:                                           /* Circle 3 points */
  1769.             circle_3pts ();
  1770.             break;
  1771.  
  1772.          case 4:                                           /* Circle tan line pt */
  1773.             circle_tan_line_pt ();
  1774.             break;
  1775.  
  1776.          case 5:                                           /* Circle tan line 2 pts */
  1777.             circle_tan_line_2pts ();
  1778.             break;
  1779.  
  1780.          case 6:                                           /* Circle tan 2 lines */
  1781.             circle_tan_2lines ();
  1782.             break;
  1783.  
  1784.          case 7:
  1785.             circle_tan_2lines_pt ();                       /* Circle tan 2 lines pt */
  1786.             break;
  1787.  
  1788.          case 8:                                           /* Circle tan 3 lines */
  1789.             circle_tan_3lines ();
  1790.             break;
  1791.  
  1792.          case 9:                                           /* Circle tan 2 arcs */
  1793.             circle_tan_2arcs ();
  1794.             break;
  1795.  
  1796.          case 11:                                          /* Circle tan arc and line */
  1797.             circle_tan_arc_line ();
  1798.             break;
  1799.  
  1800.          case 12:                                          /* Line 2pts */
  1801.             line_2pts ();
  1802.             break;
  1803.  
  1804.          case 13:                                           /* Line horizontal */
  1805.             line_pt_angle_distance ((real) 0.0);
  1806.             break;
  1807.  
  1808.          case 14:                                           /* Line vertical */
  1809.             line_pt_angle_distance ((real) 90.0);
  1810.             break;
  1811.  
  1812.          case 15:                                           /* Line parallel */
  1813.             line_parallel ();
  1814.             break;
  1815.  
  1816.          case 16:                                           /* Line perp to */
  1817.             line_perpendicular ();
  1818.             break;
  1819.  
  1820.          case 18:                                           /* Line tan pt arc */
  1821.             line_tan_arc ();  
  1822.             break;
  1823.  
  1824.          case 19:                                           /* Line tan 2 arcs */
  1825.             line_tan_2arcs ();
  1826.             break;
  1827.  
  1828.          case 20:                                           /* Point */
  1829.             point ();
  1830.             break;
  1831.  
  1832.          case 21:                                           /* Delete */
  1833.             delete_element ();
  1834.             break;
  1835.  
  1836.          default:
  1837.             break;
  1838.       }
  1839.    }
  1840.  
  1841.    cg_terminate ();
  1842. }
  1843.